<?php

namespace dk\core;
use Exception;
use HTMLPurifier;
use HTMLPurifier_Config;

abstract class Action{
    use Plug;
    use \dk\traits\Adapter;

    /**
     * @var View
     */
    protected $document;
    protected $fixTplPath;
    protected $isModule = false;
    
    protected $_layout;
    
    public function __construct($view = null){
        $this->setDocument($view);
    }
    
    public function isModule(){
        return $this->isModule;
    }

    /**
     * @param \dk\core\View $document
     */
    public function setDocument($document) {
        $this->document = $document;
    }

    public function assign($k, $value){
        $this->document->assign($k, $value);
    }

    public function setTpl($tpl, $layout = true){
        $this->document->setTpl($tpl);
        if($layout && $this->_layout){
            $this->setLayout();
        }
    }

    public function url($action, $args = []){
        if(!isset($this->plugs['url'])){
            throw(new Exception("Invalid method(url)"));
        }
        return $this->plugs['url']($action, $args);
    }

    public function getDocument(){
        return $this->document;
    }

    abstract function execute();

    /**
     * @param $k
     * @param null $def
     * @return array|\Purified
     */
    protected function requestVar($k, $def = null){
        return $this->safe(gav($_REQUEST, $k, $def));
    }

    protected function getVar($k, $def = null){
        return $this->safe(gav($_GET, $k, $def));
    }

    protected function postVar($k, $def = null){
        return $this->safe(gav($_POST, $k, $def));
    }

    protected function getInt($k, $def = 0){
        return intval($this->requestVar($k, $def));
    }

    protected function safe($html, $config = 'gbk'){
        if(!$html){
            return $html;
        }

        if(is_numeric($html) || is_bool($html)){
            return $html;
        }

        static $purifier = false;
        if (!$purifier) {
            $purifier = new HTMLPurifier();
        }

        if(!is_object($config)){
            static $defconfig = false;
            if(!$defconfig){
                $defconfig = HTMLPurifier_Config::createDefault();
                $defconfig->set('Core.Encoding', $config);
                $defconfig->set('HTML.Doctype', 'XHTML 1.0 Transitional');
            }
            $config = $defconfig;
        }

        if(is_array($html)){
            foreach ($html as $k => $value) {
                $html[$k] = $this->safe($value, $config);
            }
            return $html;
        }else{
            return $purifier->purify($html, $config);
        }
    }

    function redirect($url, $moved = true){
        header($moved ? 'HTTP/1.1 301 Moved Permanently' : 'HTTP/1.1 303 See other');
        header('Location: '.$url);
        exit;
    }
    
    protected function setLayout(){
        $this->document->setLayout($this->_layout);
    }
    
    protected function setDefaultTpl(){
        $doc = $this->getDocument();
        // set template
        if($this->fixTplPath){//ģ����Ŀ¼
            $action = $this->getTask('action');
            $do = $this->getTask('do');
            $tpl = $action . '/' . $do . '.php';
        } else {
            $action = $this->getTask();
            $tpl = $action . '.php';
        }
        
        if(!$doc->exist($tpl)){
            $tpl = 'page/' . $tpl;
            $doc->setTpl($tpl);
            if($this->_layout){
                $this->setLayout();
            }
        }else{
            $this->setTpl($tpl);
        }
        // template, action
        $this->assign('action', $action);
    }
    protected $task;
    protected function getTask($part = ''){
        if(isset($this->$part)){
            return $this->$part;
        }
        if(!$this->task){
            $name = str_replace('\\', '.', $this->getName());
        } else {
            $name = $this->task;
        }
        if($part){
            $tmp = explode('.', $name);
            switch ($part) {
                case 'action':
                    return $this->action = $tmp[0];
                case 'do':
                    return $this->do = gav($tmp, 1, 'index');
            }
        }

        return $name;
    }
    
    /**
     * @return null|string
     */
    protected function getName(){
        if(!isset($this->name)){
            $this->name = str_replace('action\\', '', get_class($this));
            $this->name = strtolower($this->name);
        }
        return $this->name;
    }
    
    public function setName($name){
        $this->name = $name;
    }
    
}